import 'package:bai_le_men_im/cmomon/utils.dart';
import 'package:bai_le_men_im/conversation/groupMessagesPage.dart';
import 'package:flutter/material.dart';

import '../constants.dart' show AppColors, AppStyles, Constants, Routes;
import '../modal/conversation.dart'
    show Conversation, Device, ConversationPageData;
import 'package:intl/intl.dart';
import '../cmomon/global.dart' as GlobalData;
import '../models/index.dart';
import '../conversation/messagesPage.dart';
import 'package:flutter_wildfire/flutter_wildfire.dart';
import 'package:async/async.dart';
import 'dart:convert';

final DateFormat formatter = new DateFormat('HH:mm');

class ConversationListPage extends StatefulWidget {
  @override
  _ConversationListState createState() => _ConversationListState();
}

class _ConversationListState extends State<ConversationListPage>
    with AutomaticKeepAliveClientMixin {
  final AsyncMemoizer _memoizer = AsyncMemoizer();
  List conversations;
  getConversations() async {
    var result =
        await FlutterWildfire.getConversationList(['Single', 'Group'], [0]);
    this.setState(() {
      conversations = result;
    });
  }

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    FlutterWildfire.on("receiveMessage", receiveMessagesHandler);
    getConversations();
    super.initState();
  }

  receiveMessagesHandler(dynamic messages) async {
    var message = messages[0];
    receiveMessageHandler(message, false);
  }

  receiveMessageHandler(dynamic message, bool clearUnRead) async {
    String target = message['conversation']['target'];
    String sender = message['sender'];
    String type = message['type'];
    int messageUid = message['messageUid'];
    // 如果是正在输入，则不做任何动作
    if (type == 'TypingMessageContent') return;

    // resetConversations:
    // 1、先找到列表中已经存在的会话，
    // 2、如果找到，临时记录它的未读值，把它删除。
    // 3、新增加一个会话, 未读值视情况加1

    // resetConversations-1
    int index = conversations.indexWhere((item) {
      var conversation = item['conversation'];
      return conversation['target'] == target;
    });
    if (clearUnRead) {
      if (index > -1) {
        if (conversations[index]["lastMessage"]['messageUid'] != 0 &&
            messageUid == conversations[index]["lastMessage"]['messageUid']) {
          setState(() {
            conversations[index]["unreadCount"]["unread"] = 0;
          });
          return;
        }
      }
    }
    // resetConversations-2
    var oldUnread = 0;
    if (index > -1) {
      oldUnread = conversations[index]["unreadCount"]["unread"];
      conversations.removeAt(index);
    }
    if (['DismissGroupNotificationContent'].contains(type)) {
      return;
    }
    if (['QuitGroupNotificationContent'].contains(type)) {
      if (message['content']['fromSelf']) {
        return;
      }
    }
    // resetConversations-3
    // 构建一个新会话
    Map newConversation = {
      "unreadCount": {
        "unreadMention": 0,
        "unreadMentionAll": 0,

        // TODO: 这里不一定要加一,如果当前路由正在和某人说话，则不需要加1
        "unread": clearUnRead ? 0 : (oldUnread + 1)
      },
      // TODO: 时间戳
      "timestamp": message['serverTime'],
      // TODO: 是否置顶
      "isTop": false,
      // TODO: 是否静音
      "isSilent": false,
      "draft": "",
      "conversation": message['conversation'],
      "lastMessage": message,
      'type': type
    };
    // TODO: 这里direction在message中没有定义
    newConversation["lastMessage"]['direction'] = "Receive";
    // print(newConversation);
    setState(() {
      conversations.insert(0, newConversation);
    });
    //
  }

  clearMessagesHandler(dynamic target) {
    String targetId;
    String targetType;
    if (target is User) {
      targetId = target.uid;
      targetType = 'Single';
    } else if (target is Group) {
      targetId = target.target;
      targetType = 'Group';
    }
    if (targetId == null) return;
    int index = conversations.indexWhere((item) {
      var conversation = item['conversation'];
      return conversation['target'] == targetId;
    });
    if (index > -1) {
      var obj = conversations[index];
      try {
        obj['lastMessage']["content"]["content"] = "";
        if (obj['lastMessage']["content"]['type'] != null) {
          obj['lastMessage']["content"].remove('type');
        }
        obj["unreadCount"]["unread"] = 0;
        FlutterWildfire.clearUnreadStatus(targetType, target, 0);
        this.setState(() {
          // conversations.removeAt(index);
        });
      } catch (e) {
        print('删除最后一条消息错误');
      }
    }
  }

  _removeConversationHandler(conversationType, target) {
    int index = conversations.indexWhere((item) {
      var conversation = item['conversation'];
      return conversation['target'] == target;
    });
    if (index > -1) {
      this.setState(() {
        conversations.removeAt(index);
      });
    }
  }

  @override
  void dispose() {
    FlutterWildfire.off("receiveMessage", receiveMessagesHandler);
    // FlutterWildfire.disconnect();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: const Color(AppColors.BackgroundColor),
      child: conversations == null
          ? Center(
              child: CircularProgressIndicator(),
            )
          : ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                var data = conversations[index];
                String formatted = formatter.format(
                    DateTime.fromMillisecondsSinceEpoch(data['timestamp']));
                if (data['lastMessage'] == null) {
                  return Container();
                }
                String type = data['lastMessage']["conversation"]['type'];
                bool isGroup = type == 'Group';
                var content = data['lastMessage']['content'];
                String contentStr;
                if (content["tip"] != null) {
                  contentStr = content["tip"];
                } else if (data['type'] != null &&
                    [
                      'QuitGroupNotificationContent',
                      'DismissGroupNotificationContent'
                    ].contains(data['type'])) {
                       contentStr = '有人退出了群聊';
                       // TODO : 谁
                } else if (['RedEnvelopeMessageContent'].contains(data['lastMessage']['type']) ||
                    content["content"] is String ||
                    content["content"] is MessageTypeRedEnvelope) {
                  if (content['type'] != null) {
                    switch (content['type']) {
                      case 1001:
                        try {
                          MessageTypeRedEnvelope msgPayload;
                          if (content['content'] is MessageTypeRedEnvelope) {
                            msgPayload = content['content'];
                          } else {
                            msgPayload = MessageTypeRedEnvelope.fromJson(
                                jsonDecode(content['content']));
                          }
                          content['content'] = msgPayload;
                          contentStr = '[积分红包]';
                        } catch (e) {
                          contentStr = '[积分红包]';
                        }

                        break;
                      default:
                        contentStr = '[积分红包]';
                        break;
                    }
                  } else {
                    contentStr = content["content"];
                  }
                } else if (content["audioOnly"] == false &&
                    content["callId"] != null) {
                  contentStr = '[视频通话]';
                  print(data);
                } else if (isGroup && content['mediaType'] == null) {
                  // contentStr = 'hello';
                  if (!content['fromSelf']) {
                    return Container();
                  }
                  if (content['operateUser'] != null) {
                    if (content['name'] != null) {
                      contentStr = (content['fromSelf']
                              ? '您'
                              : '${content['operateUser']}') +
                          '修改了群组名 ' +
                          content['name'];
                    } else {
                      // TODO: 有operateUser，没有name的情况， 是否是修改了群的别的设置
                    }
                  } else if (content['invitor'] != null &&
                      content['invitees'] != null) {
                    contentStr = '${content['invitees'].length}人被邀请进群聊';
                  } else {
                    contentStr =
                        (content['fromSelf'] ? '您' : '${content['creator']}') +
                            '创建了群组 ' +
                            content['groupName'];
                  }
                } else {
                  switch (content['mediaType']) {
                    case 'IMAGE':
                      contentStr = '[图片]';
                      break;
                    case 'FILE':
                      contentStr = '[动态表情]';
                      print(data);
                      break;
                    case 'StickerMessageContent':
                      print(data);
                      contentStr = '[表情]';
                      break;
                    case 'VOICE':
                      contentStr = '[语音]';
                      break;
                    default:
                      print('[未知类型]');
                      print(data);
                      contentStr = '[未知类型]';
                  }
                }
                String otherSideUserId = data["conversation"]["target"];

                return _ConversationItem(
                    key: Key(otherSideUserId),
                    clearMessagesHandler: clearMessagesHandler,
                    removeConversationHandler: _removeConversationHandler,
                    receiveMessageHandler: receiveMessageHandler,
                    conversation: Conversation(
                        type: data["conversation"]['type'],
                        des: contentStr,
                        isMute: data['isSilent'],
                        isTop: data['isTop'],
                        unreadMsgCount: data["unreadCount"]["unread"],
                        updateAt: formatted,
                        otherSideUserId: otherSideUserId,
                        title: otherSideUserId,
                        avatar: 'assets/images/default_nor_avatar.png'));
              },
              itemCount: conversations.length,
            ),
    );
  }
}

class _ConversationItem extends StatelessWidget {
  final Function receiveMessageHandler;
  final Function removeConversationHandler;
  static const VERTICAL_PADDING = 12.0;
  static const HORIZONTAL_PADDING = 18.0;
  static const UN_READ_MSG_CIRCLE_SIZE = 20.0;
  static const UN_READ_MSG_DOT_SIZE = 12.0;
  final Function clearMessagesHandler;

  _ConversationItem(
      {Key key,
      this.conversation,
      this.tapPos,
      @required this.receiveMessageHandler,
      @required this.clearMessagesHandler,
      this.removeConversationHandler})
      : assert(conversation != null),
        super(key: key);

  final Conversation conversation;
  var tapPos;

  _showMenu(BuildContext context, Offset tapPos) async {
    final RenderBox overlay = Overlay.of(context).context.findRenderObject();
    final RelativeRect position = RelativeRect.fromLTRB(tapPos.dx, tapPos.dy,
        overlay.size.width - tapPos.dx, overlay.size.height - tapPos.dy);
    return await showMenu<String>(
        context: context,
        position: position,
        items: <PopupMenuItem<String>>[
          PopupMenuItem(
            child: Text(Constants.MENU_MARK_AS_UNREAD_VALUE),
            value: Constants.MENU_MARK_AS_UNREAD,
          ),
          PopupMenuItem(
            child: Text(Constants.MENU_PIN_TO_TOP_VALUE),
            value: Constants.MENU_PIN_TO_TOP,
          ),
          PopupMenuItem(
            child: Text(Constants.MENU_DELETE_CONVERSATION_VALUE),
            value: Constants.MENU_DELETE_CONVERSATION,
          ),
        ]).then<String>((String selected) async {
      return selected;
    });
  }

  bool _isAvatarFromNet(avatar) {
    if (avatar.indexOf('http') == 0 || avatar.indexOf('https') == 0) {
      return true;
    }
    return false;
  }

  Widget getAvatarWidget(User user) {
    String avatarStr;
    if (user.portrait != null && user.portrait.length > 0) {
      avatarStr = user.portrait;
    } else {
      avatarStr = 'assets/images/default_nor_avatar.png';
    }

    Widget avatar;
    if (_isAvatarFromNet(avatarStr)) {
      avatar = Image.network(
        avatarStr,
        width: Constants.ConversationAvatarSize,
        height: Constants.ConversationAvatarSize,
        fit: BoxFit.cover,
      );
    } else {
      avatar = Image.asset(
        avatarStr,
        width: Constants.ConversationAvatarSize,
        height: Constants.ConversationAvatarSize,
        fit: BoxFit.cover,
      );
    }
    return avatar;
  }

  final AsyncMemoizer _memoizer = AsyncMemoizer();

  getOtherSideInfo() {
    return _memoizer.runOnce(() async {
      if (conversation.type == 'Single') {
        String userId = conversation.otherSideUserId;
        Map result = await FlutterWildfire.getUserInfo(userId, true);
        User user = User.fromJson(result);
        return user;
      }
      if (conversation.type == 'Group') {
        String groupId = conversation.otherSideUserId;
        Map result = await FlutterWildfire.getGroupInfo(groupId);
        Group group = Group.fromJson(result);
        return group;
        // User user = User.fromJson(result);
        // return user;
      }
      print('未知的会话类型 conversation.type');
    });
  }

  _removeConversation(conversationType, target, line) async {
    try {
      await FlutterWildfire.removeConversation(conversationType, target, line);
    } catch (e) {
      print('错误: ${Constants.MENU_DELETE_CONVERSATION}');
      print(e);
    } finally {
      this.removeConversationHandler(conversationType, target);
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: getOtherSideInfo(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.hasData) {
          // 根据图片的获取方式初始化头像组件
          User user;
          Widget avatar;
          String displayName;
          Group group;
          if (snapshot.data is User) {
            user = snapshot.data;
            avatar = myAvatar(user.portrait);
            displayName =
                user.friendAlias != null && user.friendAlias.isNotEmpty
                    ? user.friendAlias
                    : user.displayName;
          }
          if (snapshot.data is Group) {
            group = snapshot.data;
            avatar = myAvatar(group.portrait);
            displayName = group.name;
            // TODO: 群组的alia
          }

          avatar = ClipRRect(
            borderRadius: BorderRadius.circular(Constants.AvatarRadius),
            child: avatar,
          );

          Widget avatarContainer;
          if (conversation.unreadMsgCount > 0) {
            // 未读消息角标
            Widget unreadMsgCountText;
            if (conversation.displayDot) {
              unreadMsgCountText = Container(
                width: UN_READ_MSG_DOT_SIZE,
                height: UN_READ_MSG_DOT_SIZE,
                decoration: BoxDecoration(
                  borderRadius:
                      BorderRadius.circular(UN_READ_MSG_DOT_SIZE / 2.0),
                  color: Color(AppColors.NotifyDotBg),
                ),
              );
            } else {
              unreadMsgCountText = Container(
                width: UN_READ_MSG_CIRCLE_SIZE,
                height: UN_READ_MSG_CIRCLE_SIZE,
                alignment: Alignment.center,
                decoration: BoxDecoration(
                  borderRadius:
                      BorderRadius.circular(UN_READ_MSG_CIRCLE_SIZE / 2.0),
                  color: Color(AppColors.NotifyDotBg),
                ),
                child: Text(conversation.unreadMsgCount.toString(),
                    style: AppStyles.UnreadMsgCountDotStyle),
              );
            }

            avatarContainer = Stack(
              overflow: Overflow.visible,
              children: <Widget>[
                avatar,
                Positioned(
                  right: conversation.displayDot ? -4.0 : -6.0,
                  top: conversation.displayDot ? -4.0 : -6.0,
                  child: unreadMsgCountText,
                )
              ],
            );
          } else {
            avatarContainer = avatar;
          }

          // 勿扰模式图标
          var _rightArea = <Widget>[
            Text(conversation.updateAt, style: AppStyles.DesStyle),
            SizedBox(height: 10.0),
          ];
          if (conversation.isMute) {
            _rightArea.add(Icon(
                IconData(
                  0xe755,
                  fontFamily: Constants.IconFontFamily,
                ),
                color: Color(AppColors.ConversationMuteIcon),
                size: Constants.ConversationMuteIconSize));
          } else {
            _rightArea.add(Icon(
                IconData(
                  0xe755,
                  fontFamily: Constants.IconFontFamily,
                ),
                color: Colors.transparent,
                size: Constants.ConversationMuteIconSize));
          }
          String conversationType;
          String target;
          if (snapshot.data is User) {
            conversationType = 'Single';
            target = user.uid;
          } else {
            conversationType = 'Group';
            target = group.target;
          }
          return Material(
            color: conversation.isTop ? Colors.grey[100] : Color(AppColors.ConversationItemBg),
            child: InkWell(
              onTap: () async {
                GlobalData.Global.isReFetchWhenReseveMessage = false;
                if (snapshot.data is User) {
                  conversationType = 'Single';
                  target = user.uid;
                } else {
                  conversationType = 'Group';
                  target = group.target;
                }
                var result = await Navigator.of(context)
                    .push(new MaterialPageRoute(builder: (context) {
                  if (snapshot.data is User) {
                    return MessagesPage(
                        user: user,
                        clearMessagesHandler: () {
                          clearMessagesHandler(user);
                        });
                  } else {
                    return GroupMessagesPage(
                        groupInfo: group,
                        clearMessagesHandler: () {
                          clearMessagesHandler(group);
                        });
                  }
                }));
                if (result != null) {
                  receiveMessageHandler(result, true);
                }
                try {
                  GlobalData.Global.isReFetchWhenReseveMessage = true;
                  // this.refreshConversationList();
                  // TODO: 这里如果先清除再刷新就会刷新失败
                  await FlutterWildfire.clearUnreadStatus(
                      conversationType, target, 0);
                } catch (e) {
                  print('出错了');
                  print(e);
                }
              },
              onTapDown: (TapDownDetails details) {
                tapPos = details.globalPosition;
              },
              onLongPress: () async {
                var result = await _showMenu(context, tapPos);
                print(result);
                switch (result) {
                  case Constants.MENU_DELETE_CONVERSATION:
                    await _removeConversation(conversationType, target, 0);
                    break;
                  default:
                    print('当前选中的是3：$result');
                }
              },
              child: Container(
                padding: const EdgeInsets.only(left: HORIZONTAL_PADDING),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    avatarContainer,
                    Container(width: 12.0),
                    Expanded(
                        child: Container(
                      padding: const EdgeInsets.only(
                          right: HORIZONTAL_PADDING,
                          top: VERTICAL_PADDING,
                          bottom: VERTICAL_PADDING),
                      decoration: BoxDecoration(
                          border: Border(
                        bottom: BorderSide(
                            width: Constants.DividerWidth,
                            color: Color(AppColors.DividerColor)),
                      )),
                      child: Row(
                        children: <Widget>[
                          Expanded(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: <Widget>[
                                Text(
                                  displayName,
                                  style: AppStyles.TitleStyle,
                                  overflow: TextOverflow.ellipsis,
                                ),
                                SizedBox(height: 2.0),
                                Text(conversation.des,
                                    style: AppStyles.DesStyle, maxLines: 1)
                              ],
                            ),
                          ),
                          Container(width: 10.0),
                          Column(
                            children: _rightArea,
                          ),
                        ],
                      ),
                    )),
                  ],
                ),
              ),
            ),
          );
        } else {
          return Container();
        }
      },
    );
  }
}
